package com.zzh.net;

import android.widget.Toast;

import com.google.gson.JsonParseException;
import com.zzh.net.Utils.ToastUtils;
import com.zzh.net.exception.NoDataExceptionException;
import com.zzh.net.exception.ServerResponseException;

import org.json.JSONException;

import java.io.InterruptedIOException;
import java.net.ConnectException;
import java.net.UnknownHostException;
import java.text.ParseException;

import io.reactivex.Observer;
import io.reactivex.disposables.Disposable;
import retrofit2.HttpException;


public abstract class RxCallback<T> implements Observer<T> {

    @Override
    public void onSubscribe(Disposable d) {

    }

    @Override
    public void onNext(T response) {
        onSuccess(response);
    }

    @Override
    public void onError(Throwable e) {
//        Logger.e(e.getMessage());
        onFail(e);
        onComplete();
    }

    @Override
    public void onComplete() {
    }

    public boolean isShowToast() {
        return true;
    }

    /**
     * 请求成功
     *
     * @param result 服务器返回的数据
     */
    abstract public void onSuccess(T result);

    /**
     * 服务器返回数据，但响应码不为200
     *
     */
    /**
     * 服务器返回数据，但响应码不为1000
     */
    public void onFail(Throwable e) {
        if (e instanceof HttpException) {     //   HTTP错误
            onException(ExceptionReason.BAD_NETWORK);
        } else if (e instanceof ConnectException
                || e instanceof UnknownHostException) {   //   连接错误
            onException(ExceptionReason.CONNECT_ERROR);
        } else if (e instanceof InterruptedIOException) {   //  连接超时
            onException(ExceptionReason.CONNECT_TIMEOUT);
        } else if (e instanceof JsonParseException
                || e instanceof JSONException
                || e instanceof ParseException) {   //  解析错误
            onException(ExceptionReason.PARSE_ERROR);
        } else if (e instanceof ServerResponseException) {
            if (NetConstants.SERVER_ERROR.equals(e.getMessage())) {
                ToastUtils.show(" 您的账号已在另一台设备上登录，请重新登录", Toast.LENGTH_SHORT);
                tokenTimeOut();
            } else {
                onCodeError();
                if (!isShowToast()) return;
                ToastUtils.show(e.getMessage(), Toast.LENGTH_SHORT);
            }
        } else if (e instanceof NoDataExceptionException) {
            onSuccess(null);
        } else {
            onException(ExceptionReason.UNKNOWN_ERROR);
        }
    }

    /**
     * 请求异常
     *
     * @param reason
     */
    public void onException(ExceptionReason reason) {
        if (!isShowToast()) return;
        switch (reason) {
            case CONNECT_ERROR:
                ToastUtils.show(R.string.connect_error, Toast.LENGTH_SHORT);
                break;

            case CONNECT_TIMEOUT:
                ToastUtils.show(R.string.connect_timeout, Toast.LENGTH_SHORT);
                break;

            case BAD_NETWORK:
                ToastUtils.show(R.string.bad_network, Toast.LENGTH_SHORT);
                break;

            case PARSE_ERROR:
                ToastUtils.show(R.string.parse_error, Toast.LENGTH_SHORT);
                break;

            case UNKNOWN_ERROR:
            default:
                ToastUtils.show(R.string.unknown_error, Toast.LENGTH_SHORT);
                break;
        }
    }

    public void onCodeError () {

    }

    protected void tokenTimeOut() {

    }

    /**
     * 请求网络失败原因
     */
    public enum ExceptionReason {


        /**
         * 解析数据失败
         */
        PARSE_ERROR,
        /**
         * 网络问题
         */
        BAD_NETWORK,
        /**
         * 连接错误
         */
        CONNECT_ERROR,
        /**
         * 连接超时
         */
        CONNECT_TIMEOUT,

        /**
         * 未知错误
         */
        UNKNOWN_ERROR,

        /**
         * 服务器错误
         */
        SERVER_ERROR,
    }

}
